#include "../inc/skyObject.h"
#include "../inc/skyString.h"
#include "../inc/skyStd.h"

namespace Sky
{
	TVoid* Memory::alloc( size_t size )
	{
		alloc_count ++;
		return ::malloc(size);
	}

	TVoid Memory::free( TVoid* p )
	{

		free_count ++;
		::free(p);
		return;
	}

	TVoid Memory::copy( TVoid* dst,const TVoid* src,size_t size )
	{
		memcpy(dst,src,size);
		return;
	}

	TVoid*  Memory::operator new( size_t size )
	{
		return Memory::alloc(size);
	}

	TVoid*  Memory::operator new[]( size_t size )
	{
		return Memory::alloc(size);
	}

	TVoid* Memory::clone( size_t size,const TVoid* src )
	{
		TVoid* p = alloc(size);
		if( p == vNull)return vNull;
		copy(p,src,size);
		return p;
	}

	TVoid* Memory::realloc( TVoid* p,size_t size )
	{
		TVoid* pnew = ::realloc(p,size);
		xAssert(pnew);
		if( pnew == vNull)
		{
			return vNull;
		}
		return pnew;
	}

	TVoid Memory::set( TVoid* dst,TUint n,size_t size )
	{
		::memset(dst,n,size);
	}

	int Memory::free_count = 0;

	int Memory::alloc_count = 0;

	void  Memory::operator delete( void* p )
	{
		return Memory::free(p);
	}

	void  Memory::operator delete[]( void* p )
	{
		return Memory::free(p);
	}

	PtrWrapper::~PtrWrapper()
	{
		if(ptr)ptr->decRef();
	}

	StringPtr Object::toString(StringPtr str)
	{
		TChar* p = _XT("Object");
		String::staticString s(p);
		if(!str)str = skynew(String());
		*str = String(s);
		return str;
	}

	TVoid Object::incRef()
	{
		if(!isOnHeap())return;
		_ref++;
		return ;
	}

	TVoid Object::decRef()
	{
		if(!isOnHeap())return;
		--_ref;
		if(_ref == 0)
		{
			delete this;
			return ;
		}
		return ;
	}

	Object::~Object()
	{
		//std::cout<<"deleted: --->"<<std::endl;
	}

	Object::Object() :_ref(0x80000000)
	{
		//std::cout<<"created:---<"<<std::endl;
	}

	TBool Object::cloneFrom(const Object* other )
	{
		if(other->isExactKindOf(Object::Class))
		{
			Memory::copy(this,other,sizeof(Object));
			return vTrue;
		}
		return vFalse;
	}


	//template <typename CLS>
	//void RefPtr<CLS>::operator=( CLS* p )
	//{
	//	if(p)p->incRef();
	//	if(ptr)ptr->decRef();
	//	ptr = p;
	//}


	//template <typename CLS>
	//CLS* RefPtr<CLS>::operator->()
	//{
	//	return leakPtr();
	//}

}